/**
 * Template that does a linear search through cells.
 **/

#pragma once
#include "Scene.h"

template <class CellType>
class LinearCellScene :
    public Scene
{
private:
    int h, w;
    CellType* cells;
public:
    //Readies this scene for ray tracing.
    void ready();

    //Assigns a heightmap to this scene.
    void assignHeightmap(Heightmap& heightmap);

    //Traces a ray into the scene. Returns the intersection.
    Intersection traceRay(Ray& ray) const;

    //Traces a shadow ray. Returns true iff there is a collision.
    bool traceShadowRay(Ray& ray) const;
};

template <class CellType>
void LinearCellScene<CellType>::ready() {

}

template <class CellType>
void LinearCellScene<CellType>::assignHeightmap(Heightmap& heightmap) {
    h = heightmap.height() - 1;
    w = heightmap.width() - 1;

    cells = new CellType[h*w];
    for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++) {
            cells[i*w+j].setFromHeightmap(heightmap, j, i);
        }
}

template <class CellType>
Intersection LinearCellScene<CellType>::traceRay(Ray& ray) const {
    Ray tracedRay = ray;
    Intersection result;
    for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++) {
            Intersection hit = cells[i*w+j].traceRay(tracedRay);
            if (hit.exists()) {
                result = hit;
                tracedRay.maxT = hit.t;
            }
        }

    return result;
}

template <class CellType>
bool LinearCellScene<CellType>::traceShadowRay(Ray& ray) const {
    return traceRay(ray).exists();
}